package paythere

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"sort"
)

// md5Hash returns the MD5 hash of the given byte slice.
func md5Hash(data []byte) []byte {
	hasher := md5.New()
	hasher.Write(data)
	return hasher.Sum(nil)
}

// GenerateSignature generates a signature based on the given parameters and secret.
func GenerateSignature(params map[string]any, secret string) (string, error) {
	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	var paramBuffer bytes.Buffer
	for _, key := range keys {
		value, ok := params[key]
		if !ok {
			continue
		}
		if value == nil || fmt.Sprint(value) == "" || key == "sign" {
			continue
		}
		// Append key=value& to buffer
		paramBuffer.WriteString(key)
		paramBuffer.WriteByte('=')
		paramBuffer.WriteString(fmt.Sprint(value))
		paramBuffer.WriteByte('&')
	}

	// Generate the first MD5 hash
	firstHash := hex.EncodeToString(md5Hash(paramBuffer.Bytes()))

	// Generate the final signature by concatenating the first hash and the secret, then hashing again
	finalHash := hex.EncodeToString(md5Hash([]byte(firstHash + secret)))

	return finalHash, nil
}
